require "wondercap/lib/multi_configuration/task_executor"

namespace :wondercap do

  task :extract_filters do
    next if fetch(:filters, "").respond_to? :push

    set :filters, fetch(:filters, "").split(/,/)
    if exists?(:tags) && !filters.include?("tags")
      filters.insert 0, "tags"
    end
  end
  after "wondercap:process_multi_configuration_files", "wondercap:extract_filters"
  before "wondercap:filter_names", "wondercap:extract_filters"
  
  task :extract_names do
    next if fetch(:names, "").respond_to? :push
    
    set :supplied_names, fetch(:names, "").split(/,/)
    if (supplied_names[0] || "").casecmp("all") == 0
      set :supplied_names, configurations_names.map { |name| name.to_s }
    end
    set :names, supplied_names.dup
  end
  after "wondercap:process_multi_configuration_files", "wondercap:extract_names"  
  before "wondercap:filter_names", "wondercap:extract_names"
  
  task :filter_names do
    filters.insert 0, :only_existing_initial_names
    filters << :existing_configurations_only
    
    outer_conf = self
    configurations = Hash.new { |h,k| h[k] = (configuration_defined?(k) ? configuration_clone(k) : nil) }
    
    logger.info "applying name filters: #{filters.join(",")}"
    logger.info "names before filtering: #{names.join(",")}"
    filters.each do |filter|
      logger.debug "applying filter: #{filter}"
      
      prev_names = names.dup
      set :names, get_name_filter(filter).call(names, configurations, Hash.new { |h,k| outer_conf.fetch(k, nil) })
      
      logger.debug "filter applied: #{filter}\nnames before: #{prev_names.join(",")}\nnames after: #{names.join(",")}"
    end
    
    set :filtered_configurations, names.map { |name| configurations[name] }
    logger.info "names after filtering: #{names.join(",")}"
  end
  
  task :list_names do
    ui.say "supplied names: #{supplied_names.join(",")}"
    ui.say "names after filtering: #{names.join(",")}"
    
    ui.say(ui.list(names)) unless names.empty?
  end
  before "wondercap:list_names" do
    filters.insert 0, :append_required_dependencies if fetch(:with_deps, false)
    filters.insert 0, :order_by_dependencies_filter if fetch(:order, false)    
    filter_names
  end
  
  before "wondercap:execute_task_on_names", "wondercap:filter_names"
  after "wondercap:extract_filters" do
    if top_task.fully_qualified_name == "wondercap:execute_task_on_names"
      filters << :task
    end
  end
  task :execute_task_on_names do
    options = {}
    options[:ignore_errors] = true if fetch(:ignore_errors, false)
    task_name = fetch :task
    begin
      Wondercap::TaskExecutor.execute(task_name, filtered_configurations, options)
      trigger :task_succeeded
    rescue Wondercap::TaskExecutorError => e
      trigger :task_failed
      raise e
    end
  end
  
end